home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et-2_2.lha / et2.2 / src / String.C < prev    next >
C/C++ Source or Header  |  1990-12-04  |  8KB  |  430 lines

  1. #include "String.h"
  2. #include "Error.h"
  3.  
  4. #define VPRINTF
  5.  
  6. static char *hexChars= "0123456789abcdef";
  7. static int col;
  8.  
  9.  
  10. #ifndef VPRINTF
  11. #   ifdef DOPRNT
  12.  
  13. #       define vsprintf(s,f,p) _doprnt(f,p,s)
  14.     extern "C" int _doprnt(const char*, va_list, char*);
  15.  
  16. #   else DOPRNT
  17.  
  18.     char *vsprintf(char *buf, const char *fmt, va_list ap)
  19.     {
  20.         int *ip= (int*) ap;
  21.         return sprintf(buf, fmt, ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], 
  22.                            ip[6], ip[7], ip[8], ip[9]);
  23.     }
  24.  
  25. #   endif DOPRNT
  26. #endif VPRINTF
  27.  
  28.  
  29. int StuffChar(char *src, char *dst, int dstlen, char* specchars, char stuffchar)
  30. {
  31.     register char *p, *q, *end;
  32.  
  33.     end= dst+dstlen-1;
  34.  
  35.     for (p= src, q= dst; *p && q < end; ) {
  36.     if (index(specchars, *p)) {
  37.         *q++= stuffchar;
  38.         if (q < end)
  39.         *q++= *p++;
  40.     } else 
  41.         *q++= *p++;
  42.     }
  43.     *q= '\0';
  44.  
  45.     if (*p != 0)
  46.     return -1;
  47.     return q-dst;
  48. }
  49.  
  50. static int readchar(istream &i, byte end)
  51. {
  52.     byte c;
  53.     int d, k, j;
  54.  
  55.     for (;;) {
  56.     i.get(c);
  57.     if (i.rdstate() != _good || c == end)
  58.         return -1;
  59.     switch (c) {
  60.     case '\\':
  61.         i.get(c);
  62.         switch (c) {
  63.         case 'n':
  64.         return '\n';
  65.         case 'r':
  66.         return '\r';
  67.         case 'b':
  68.         return '\b';
  69.         case 'f':
  70.         return '\f';
  71.         case 't':
  72.         return '\t';
  73.         case 'v':
  74.         return '\v';
  75.         case 'x':
  76.         for (k= j= 0; j < 2 && k < 256; j++) {
  77.             i.get(c);
  78.             if (! Isxdigit(c)) {
  79.             i.putback(c);
  80.             break;
  81.             }
  82.             if (Isdigit(c))
  83.             d= c - '0';
  84.             else if (Islower(c))
  85.             d= c - 'a' + 10;
  86.             else
  87.             d= c - 'A' + 10;
  88.             k= k*16 + d;
  89.         }
  90.         return k;
  91.  
  92.         case '0': case '1': case '2': case '3': case '4':
  93.         case '5': case '6': case '7':
  94.         for (k= j= 0; j < 3 && k < 256; j++) {
  95.             k= k*8 + c - '0';
  96.             i.get(c);
  97.             if (c < '0' || c > '7')
  98.             break;
  99.         }
  100.         i.putback(c);
  101.         return k;
  102.  
  103.         default:
  104.         return c;
  105.         }
  106.         break;
  107.  
  108.     default:
  109.         if (Isprint(c))
  110.         return c;
  111.         break;
  112.     }
  113.     }
  114. }
  115.  
  116. istream &ReadString(istream &i, byte **s, int *lp)
  117. {
  118.     int l, c;    
  119.     byte cc, *p, *pp;
  120.  
  121.     i >> l >> cc;
  122.     pp= p= new byte[l];
  123.     if (cc == '"')
  124.     while ((c= readchar(i, '\"')) != -1)
  125.        *p++= (byte) c;
  126.     if (s)
  127.     *s= pp;
  128.     if (lp)
  129.     *lp= l;
  130.     return i;
  131. }
  132.  
  133. char ReadChar(istream &i)
  134. {
  135.     int c;    
  136.     char cc;
  137.  
  138.     i >> cc;
  139.     if (cc == '\'')
  140.     while ((c= readchar(i, '\'')) != -1)
  141.        cc= (unsigned char) c;
  142.     return cc;
  143. }
  144.  
  145. void printchar(ostream &o, byte c)
  146. {
  147.     switch(c) {
  148.     case '{':
  149.     case '}':
  150.     o.put('\\'); o.put('x'); PutHex(o, c); col+= 4;
  151.     break;
  152.     case '\n':
  153.     o.put('\\'); o.put('n'); col+= 2;
  154.     break;
  155.     case '\r':
  156.     o.put('\\'); o.put('r'); col+= 2;
  157.     break;
  158.     case '\t':
  159.     o.put('\\'); o.put('t'); col+= 2;
  160.     break;
  161.     case '\v':
  162.     o.put('\\'); o.put('v'); col+= 2;
  163.     break;
  164.     case '\f':
  165.     o.put('\\'); o.put('f'); col+= 2;
  166.     break;
  167.     case '\b':
  168.     o.put('\\'); o.put('b'); col+= 2;
  169.     break;
  170.     case '\"':
  171.     o.put('\\'); o.put('\"'); col+= 2;
  172.     break;
  173.     case '\'':
  174.     o.put('\\'); o.put('\''); col+= 2;
  175.     break;
  176.     case '\\':
  177.     o.put('\\'); o.put('\\'); col+= 2;
  178.     break;
  179.     default:
  180.     if (Isascii(c) && Isprint(c)) {
  181.         o.put(c); col++;
  182.     } else {
  183.         o.put('\\'); o.put('x'); PutHex(o, c); col+= 4;
  184.     }
  185.     }
  186. }
  187.  
  188. ostream &PrintString(ostream &o, byte *s, int l)
  189. {
  190.     if (l < 0)
  191.     l= strlen((char*)s)+1;
  192.     o << l SP;
  193.     o.put('\"');
  194.     for (col= 0; l > 0; l--) {
  195.     printchar(o, *s++);
  196.     if (col >= 72) {
  197.         o.put('\n');
  198.         col= 0;
  199.     }
  200.     }
  201.     o.put('\"');
  202.     return o;
  203. }
  204.  
  205. ostream &PrintChar(ostream &o, char c)
  206. {
  207.     o.put('\"');
  208.     printchar(o, c);
  209.     o.put('\"');
  210.     return o;
  211. }
  212.  
  213. byte GetHex(istream &s)
  214. {
  215.     char c;
  216.     unsigned short val= 0;
  217.  
  218.     for (int i= 0; i<2;) {
  219.     s.get(c);
  220.     if (Isxdigit(c)) {
  221.         if (Isdigit(c))
  222.         val= val*16 + c-'0';
  223.         else if (Isupper(c))
  224.         val= val*16 + c-'A'+10;
  225.         else 
  226.         val= val*16 + c-'a'+10;
  227.         i++;
  228.     }
  229.     }
  230.     return val;
  231. }
  232.  
  233. void PutHex(ostream &ofp, byte b, int *col)
  234. {    
  235.     ofp.put(hexChars[b/16]);
  236.     ofp.put(hexChars[b%16]);
  237.     if (col) {
  238.     (*col)++;
  239.     if (*col >= 40) {
  240.         ofp.put('\n');
  241.         *col= 0;
  242.     }
  243.     }
  244. }
  245.  
  246. char *strsave(char *s, int l)
  247. {
  248.     if (s == 0 || l == 0)
  249.     return 0;
  250.     if (l < 0)
  251.     l= strlen(s)+1;
  252.     char *str= new char[l];
  253.     return strncpy(str, s, l);
  254. }
  255.  
  256. char *strreplace(char **s, char *r, int l)
  257. {
  258.     if (s == 0)
  259.     Fatal("strreplace", "s == 0, replace: %s l: %d", r, l);
  260.     if (r == 0 || l == 0)
  261.     return *s;
  262.     if (l < 0)
  263.     l= strlen(r)+1;
  264.     *s= (char*) Realloc(*s, l);
  265.     return strncpy(*s, r, l);
  266. }
  267.  
  268. char *strfreplace(char **s, char *fmt, va_list ap)
  269. {
  270.     char buf[1000];
  271.  
  272.     if (s == 0)
  273.     Fatal("strfreplace", "s == 0, fmt: %s", fmt);
  274.     if (fmt == 0)
  275.     return *s;
  276.  
  277.     vsprintf(buf, fmt, ap);
  278.  
  279.     *s= (char*) Realloc(*s, strlen(buf)+1);
  280.     return strcpy(*s, buf);
  281. }
  282.  
  283. char *strprintf(char *va_(fmt), ...)
  284. {
  285.     va_list ap;
  286.     char buf[2000];
  287.  
  288.     va_start(ap,va_(fmt));
  289.     vsprintf(buf, va_(fmt), ap);
  290.     va_end(ap);
  291.     return strsave(buf);
  292. }
  293.  
  294. char* strvprintf(char* fmt, va_list ap)
  295. {       
  296.     char buf[2000];
  297.  
  298.     vsprintf(buf, fmt, ap);
  299.     return strsave(buf);
  300. }
  301.  
  302. bool strismember(const char *va_(cp), ...)
  303. {
  304.     char *s;   
  305.     va_list ap;
  306.     bool found= FALSE;
  307.     va_start(ap,va_(cp));
  308.     for (int i= 0; s= va_arg(ap, char*); i++)  
  309.     if (strcmp(va_(cp), s) == 0) {
  310.         found= TRUE;
  311.         break;
  312.     }
  313.     va_end(ap);
  314.     return found;
  315. }
  316.  
  317. char* strn0cpy(char *dst, const char *src, int l)
  318. {
  319.     strncpy(dst, src, l-1);
  320.     dst[l-1]= '\0';
  321.     return dst;
  322. }
  323.  
  324. char *strquotechar(byte ch, char *q)
  325. {
  326.     switch(ch) {
  327.     case '\n':
  328.     *q++='\\'; *q++='n'; 
  329.     break;
  330.     case '\r':
  331.     *q++='\\'; *q++='r'; 
  332.     break;
  333.     case '\0':
  334.     *q++='\\'; *q++='0'; 
  335.     break;
  336.     case '\t':
  337.     *q++='\\'; *q++='t'; 
  338.     break;
  339.     case '\v':
  340.     *q++='\\'; *q++='v'; 
  341.     break;
  342.     case '\f':
  343.     *q++='\\'; *q++='f'; 
  344.     break;
  345.     case '\b':
  346.     *q++='\\'; *q++='b'; 
  347.     break;
  348.     default:
  349.     if (Isascii(ch) && Isprint(ch)) {
  350.         *q++= ch;
  351.     } else {
  352.         *q++= '\\'; *q++= 'x'; *q++= hexChars[ch/16]; *q++= hexChars[ch%16]; 
  353.     }
  354.     }
  355.     return q;
  356. }
  357.  
  358. char *BaseName(char *name) 
  359. {
  360.     char *filename = rindex(name, '/');
  361.  
  362.     if (!filename)
  363.     filename= name;
  364.     else
  365.     filename++;
  366.     return filename;
  367. }
  368.  
  369. int StrCmp(register byte *s1, register byte *s2, int n, register byte *map)
  370. {
  371.     if (map) {
  372.     if (n < 0) {
  373.         while (map[(byte)*s1] == map[(byte)*s2++])
  374.         if (map[(byte)*s1++] == '\0')
  375.             return 0;
  376.         return map[(byte)*s1] - map[(byte)*--s2];
  377.     } else {
  378.         while (--n >= 0 && map[(byte)*s1] == map[(byte)*s2++])
  379.         if (map[(byte)*s1++] == '\0')
  380.             return 0;
  381.         return (n < 0) ? 0 : map[(byte)*s1] - map[(byte)*--s2];
  382.     }
  383.     } else {
  384.     if (n < 0) {
  385.         while (*s1 == *s2++)
  386.         if (*s1++ == '\0')
  387.             return 0;
  388.         return (int)*s1 - (int)*--s2;
  389.     } else {
  390.         while (--n >= 0 && *s1 == *s2++)
  391.         if (*s1++ == '\0')
  392.             return 0;
  393.         return (n < 0) ? 0 : (int)*s1 - (int)*--s2;
  394.     }
  395.     }
  396. }
  397.  
  398. const   cb_size = 1024;
  399. const   fld_size = 512;
  400.  
  401. // a circular formating buffer
  402. static char     formbuf[cb_size];       // some slob for form overflow
  403. static char*    bfree= formbuf;
  404. static char*    endbuf= &formbuf[cb_size-1];
  405.  
  406. char* form(const char* va_(fmt), ...)
  407. {
  408.     va_list ap;
  409.     va_start(ap,va_(fmt));
  410.     const char *format= va_(fmt);
  411.     register char* buf = bfree;
  412.  
  413.     if (endbuf < buf+fld_size)
  414.     buf= formbuf;
  415.  
  416.     register int ll= (int) vsprintf(buf, format, ap);
  417.     if (0 < ll && ll < cb_size)                 // length
  418.         ;
  419.     else if (buf<(char*)ll && (char*)ll<buf+cb_size)// pointer to trailing 0
  420.         ll= (char*)ll - buf;
  421.     else
  422.         ll= strlen(buf);
  423.     if (fld_size < ll)  // oops
  424.     Fatal("form", "buffer overflow");
  425.     bfree = buf+ll+1;
  426.     va_end(ap);
  427.     return buf;
  428. }
  429.  
  430.